package com.springapp.mvc.controllers;

import com.springapp.mvc.dto.DeleteMessageBody;
import com.springapp.mvc.dto.GetPostsBody;
import com.springapp.mvc.dto.PostBody;
import com.springapp.mvc.dto.PostResult;
import com.springapp.mvc.entity.UserPost;
import com.springapp.mvc.services.PostingService;
import com.springapp.mvc.util.ExecUtil;
import com.springapp.mvc.util.PostAction;
import com.springapp.mvc.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;


@Controller
@RequestMapping("/messages")
public class MessageController {

    private static final String NOT_LOGGED_MESSAGE = "You are not logged in";
    private static final String IMAGE_CORRUPTED_MESSAGE = "The image provided is corrupted";
    private static final String FAILED_TO_STORE_FILE_MESSAGE = "Problem occurred while storing file in system";

    @Autowired
    private PostingService postingService;

    @RequestMapping(value = "/delete",
                    method = RequestMethod.POST,
                    produces = MediaType.APPLICATION_JSON_VALUE,
                    consumes = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody PostResult deleteMessage(@RequestBody DeleteMessageBody postBody) {
        final Long messageId = postBody.getMessageId();
        return ExecUtil.exec(new PostAction() {
            @Override
            public void perform() {
                postingService.deleteMessage(messageId);
            }
        });
    }

    @RequestMapping(value = "/fetch",
                    method = RequestMethod.POST,
                    produces = MediaType.APPLICATION_JSON_VALUE,
                    consumes = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody List<UserPost> getPosts(@RequestBody GetPostsBody body) {
        return postingService.getPosts(body.getOffset(), body.getCount());
    }

    @Deprecated
    @RequestMapping(value = "/post",
                    method = RequestMethod.POST,
                    produces = MediaType.APPLICATION_JSON_VALUE,
                    consumes = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody PostResult postMessage(@RequestBody PostBody postBody) {
        final Long currentUserId = SecurityUtils.getCurrentUserId();
        final String message = postBody.getMessage();

        return ExecUtil.exec(new PostAction() {
            @Override
            public void perform() {
                if (currentUserId == null) {
                    throw new RuntimeException(NOT_LOGGED_MESSAGE);
                }
                postingService.addMessage(currentUserId, message);
            }
        });
    }

    @RequestMapping(value = "/create",
                    method = RequestMethod.POST,
                    consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
                    produces = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody PostResult createMessage(@RequestParam(value = "messageText", required = true) final String messageText,
                                @RequestParam(value = "imageInput", required = false) final MultipartFile image) {
        final Long currentUserId = SecurityUtils.getCurrentUserId();

        final PostAction postAction;
        if (image == null) {
            postAction = new PostAction() {
                @Override
                public void perform() {
                    if (currentUserId == null) {
                        throw new RuntimeException(NOT_LOGGED_MESSAGE);
                    }
                    postingService.addMessage(currentUserId, messageText);
                }
            };

        } else {
            postAction = new PostAction() {
                @Override
                public void perform() {
                    if (currentUserId == null) {
                        throw new RuntimeException(NOT_LOGGED_MESSAGE);
                    }

                    final byte[] imageBytes;
                    try {
                        imageBytes = image.getBytes();
                    } catch (IOException e) {
                       throw new RuntimeException(IMAGE_CORRUPTED_MESSAGE);
                    }

                    try {
                        postingService.addMessage(currentUserId, messageText, imageBytes);
                    } catch (IOException e) {
                        throw new RuntimeException(FAILED_TO_STORE_FILE_MESSAGE);
                    }
                }
            };
        }

        return ExecUtil.exec(postAction);
    }
}
